package com.iteaj.iot.codec;

import com.iteaj.iot.SocketMessage;
import com.iteaj.iot.ProtocolException;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandler;
import org.springframework.beans.BeanUtils;

/**
 * 报文{@link SocketMessage}解码器
 * 使用此解码器务必保留默认的报文构造函数{@link SocketMessage#SocketMessage(byte[])}
 */
public interface IotMessageDecoder extends ChannelInboundHandler {

    Class<? extends SocketMessage> getMessageClass();

    IotMessageDecoder setMessageClass(Class<? extends SocketMessage> messageClass);

    /**
     * 使用默认的构造函数 {@link SocketMessage#SocketMessage(byte[])} 构造实体报文
     * @param ctx
     * @param decode 可以是类型 ByteBuf、SocketMessage、null
     * @return SocketMessage 使用默认的构造函数 {@link SocketMessage#SocketMessage(byte[])}
     * @throws Exception
     */
    default SocketMessage proxy(ChannelHandlerContext ctx, ByteBuf decode) throws Exception {
        if(decode != null) {
            SocketMessage message = doDecode(ctx, decode);
            if(message != null) {
                message.build();
            }

            return message;
        } else {
            return null;
        }

    }

    /**
     * 默认的解码
     * 使用默认构造器创建报文 {@link SocketMessage#SocketMessage(byte[])}
     * @param ctx
     * @param decode
     * @return
     */
    default SocketMessage doDecode(ChannelHandlerContext ctx, ByteBuf decode) {
        int readableBytes = (decode).readableBytes();
        if(readableBytes <= 0) return null;

        byte[] message = new byte[readableBytes];
        (decode).readBytes(message);

        // 报文必须保留默认的构造函数
        try {
            return BeanUtils.instantiateClass(getMessageClass().getConstructor(byte[].class), message);
        } catch (Exception e) {
            throw new ProtocolException("找不到构造函数["+getMessageClass().getSimpleName()+"(byte[])], 请增加对应的构造函数或者自定义解码", e.getCause());
        }
    }
}
